package com.template.utils;

import jakarta.validation.ConstraintViolation;
import jakarta.validation.Validation;
import jakarta.validation.Validator;
import jakarta.validation.ValidatorFactory;
import org.hibernate.validator.HibernateValidator;
import org.springframework.util.Assert;

import java.util.Set;
import java.util.stream.Collectors;

/**
 * 参数校验工具类
 * NOTE： 具体使用参照测试类
 *
 * @since 2019/5/7
 */
public class ValidationUtils {
    /**
     * 快速校验
     */
    private static final Validator failFastValidator;

    /**
     * 全部校验
     */
    private static final Validator validator;

    static {
        ValidatorFactory factory1 = Validation.byProvider(HibernateValidator.class)
                .configure()
                .failFast(true)
                .buildValidatorFactory();
        ValidatorFactory factory2 = Validation.buildDefaultValidatorFactory();
        try (factory1; factory2) {
            failFastValidator = factory1.getValidator();
            validator = factory2.getValidator();
        }
    }

    /**
     * 验证参数(快速失败模式)
     */
    public static <T> void validFast(T obj, Class<?>... groups) {
        validFast(true, obj, groups);
    }

    /**
     * 验证参数(快速失败模式)
     */
    public static <T> void validFast(boolean condition, T obj, Class<?>... groups) {
        if (!condition) return;
        Set<ConstraintViolation<T>> validate = failFastValidator.validate(obj, groups);
        //返回异常result
        if (validate.size() > 0) {
            throw new IllegalArgumentException(validate.iterator().next().getMessage());
        }
    }

    /**
     * 注解验证参数(全部校验)
     *
     * @param obj
     */
    public static <T> void validAll(T obj, Class<?>... groups) {
        Set<ConstraintViolation<T>> validate = validator.validate(obj, groups);
        //返回异常result
        if (validate.size() > 0) {
            String message = validate.stream()
                    .map(ConstraintViolation::getMessage)
                    .collect(Collectors.joining("；"));
            throw new IllegalArgumentException(message);
        }
    }
}

